Ambiente d'esame e i suoi script
Qui di seguito sono documentati gli script dell'ambiente.
I principali sono assemble.ps1
e debug.ps1
, il cui uso è mostrato nelle esercitazioni.
Gli script run-test.ps1
e run-tests.ps1
sono utili per automatizzare i test, il loro uso è del tutto opzionale.
Aprire l'ambiente
Sulle macchine all'esame (o sulla propria, se si seguono tutti i passi indicati nel pacchetto di installazione) troverete una cartella C:/reti_logiche
con contenuto come da figura.
Facendo doppio click sul file assembler.code-workspace
verrà lanciato VS Code, collegandosi alla macchina virtuale WSL e la cartella di lavoro C:/reti_logiche/assembler
.
La finestra VS Code che si aprirà sarà simile alla seguente.
Nell'angolo in basso a sinistra, WSL: Ubuntu-22.04
sta a indicare che l'editor è correttamente connesso alla macchina virtuale.
I file e cartelle mostrati nell'immagine sono quelli che ci si deve aspettare dall'ambiente vuoto.
In caso si trovino file in più all'esame, si possono cancellare.
Il file test-ambiente.s
è un semplice programma per verificare che l'ambiente funzioni. Il contenuto è il seguente:
.include "./files/utility.s"
.data
messaggio: .ascii "Ok.\r"
.text
_main:
nop
lea messaggio, %ebx
call outline
ret
Il terminale Powershell
Per aprire un terminale in VS Code possiamo usare Terminale -> Nuovo Terminale
.
Per eseguire gli script dell'ambiente c'è bisogno di aprire un terminale Powershell.
La shell standard di Linux, bash
, non è in grado di eseguire questi script.
Non così:
Ma così:
Per cambiare shell si può usare il bottone +
sulla sinistra, o lanciare il comando pwsh
senza argomenti.
Se si preferisce, in VS Code si può aprire un terminale anche come tab dell'editor, o spostandolo al lato anziché in basso.
Perché Powershell (2006) è object-oriented, e permette di scrivere script leggibili e manutenibili, in modo semplice. Bash (1989) è invece text-oriented, con una lunga lista di trappole da saper evitare.
Eseguire gli script
Gli script forniti permettono di assemblare, debuggare e testare il proprio programma.
È importante che vengano eseguiti senza cambiare cartella, cioè non usando il comando cd
o simili.
Ricordarsi anche dei ./
, necessari per indicare al terminale che i file indicati vanno cercati nella cartella corrente.
Il tasto tab
⭾ della tastiera invoca l'autocompletamento, che aiuta ad assicurarsi di inserire percorsi corretti.
Si ricorda inoltre di salvare il file sorgente prima di provare ad eseguire script.
assemble.ps1
PS /mnt/c/reti_logiche/assembler> ./assemble.ps1 mio_programma.s
Questo script assembla un sorgente assembler in un file eseguibile.
Lo script controlla prima che il file passato non sia un eseguibile, invece che un sorgente.
Poi, il sorgente viene assemblato usando gcc ed includendo il sorgente ./files/main.c
, che si occupa di alcune impostazioni del terminale.
debug.ps1
PS /mnt/c/reti_logiche/assembler> ./debug.ps1 mio_programma
Questo script lancia il debugger per un programma.
Lo script controlla prima che il file passato non sia un sorgente, invece che un eseguibile.
Poi, il debugger gdb viene lanciato con il programma dato, includendo le definizioni e comandi iniziali in ./files/gdb_startup
.
Questi si occupano di definire i comandi qquit
e rrun
(non chiedono conferma), creare un breakpoint in _main
e avviare il programma fino a tale breakpoint (così da saltare il codice di setup di ./files/main.c
).
run-test.ps1
PS /mnt/c/reti_logiche/assembler> ./run-test.ps1 mio_programma input.txt output.txt
Lancia un eseguibile usando il contenuto di un file come input, e opzionalmente ne stampa l'output su file. Lo script fa ridirezione di input/output, con alcuni controlli. Tutti i caratteri del file di input verranno visti dal programma come se digitati da tastiera, inclusi i caratteri di fine riga.
run-tests.ps1
PS /mnt/c/reti_logiche/assembler> ./run-tests.ps1 mio_programma cartella_test
Testa un eseguibile su una serie di coppie input-output, verificando che l'output sia quello atteso. Stampa riassuntivamente e per ciascun test se è stato passato o meno.
Lo script prende ciascun file di input, con nome nella forma in_*.txt
, ed esegue l'eseguibile con tale input.
Ne salva poi l'output corrispondente nel file out_*.txt
.
Confronta poi out_*.txt
e out_ref_*.txt
: il test è passato se i due file coincidono.
Nel confronto, viene ignorata la differenza fra le sequenze di fine riga \r\n
e \n
.